package org.beetl.json.node;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

import org.beetl.json.ActionReturn;
import org.beetl.json.DirectOutputValue;
import org.beetl.json.JsonTool;
import org.beetl.json.JsonWriter;
import org.beetl.json.OutputNode;
import org.beetl.json.action.IValueAction;
import org.beetl.json.loc.IndexLocation;
import org.beetl.json.loc.IndexLocations;

class NodeUtil {
	public static void writeUnkonw(OutputNode node,Object o,JsonWriter w, TreeSet<IValueAction>  valueActions) throws IOException{
		if(valueActions.size()!=0){			
			for(IValueAction valueAction:valueActions){
				ActionReturn ar = valueAction.doit(o, node,w);	
				o = ar.value;			
				if(ar.process==ActionReturn.CONTINUE){
					break ;
				}else if(ar.process==ActionReturn.RETURN){
					return ;
				}
			}								
		}		
		
		if(o==null){
			w.writeValue(null);
			return ;
		}
		if(o instanceof Iterable){
			
			Iterator it = ((Iterable)o).iterator();
				writeIterator(node,it,w);
		}else if(o instanceof Iterator){
			writeIterator(node,(Iterator)o,w);
		}
		else if( o instanceof Map){
			writeMap(node,(Map)o,w);
		}else if (o instanceof Enumeration){
			List list = Collections.list((Enumeration)o);			
			writeIterator(node,list.iterator(),w);
		}else{
			Class cls = o.getClass();
			if(cls==DirectOutputValue.class){
				w.writeValue((DirectOutputValue)o);
			}else if( cls.isArray()){
				List list = Arrays.asList((Object[])o);
				writeIterator(node,list.iterator(),w);
			}else if(cls.getPackage().getName().startsWith("java")){
				w.writeValue(o);
			} else{
				JsonTool.serializeJW(w,o,node.getInHeritedPolicy());
			}
				
				
			
		}
	}
	
	public  static void writeMap(OutputNode node,Map map,JsonWriter w) throws IOException{
		
	
		
		IndexLocations il = node.getIndexLocation();
		Iterator<Map.Entry> it = map.entrySet().iterator();

		
		if(!it.hasNext()){
			w.writeValue("{}");
			return ;
		}
		w.writeScopeChar('{');
		boolean isFirst = true;
		while(true){
			
			Map.Entry item = it.next();
			if(il!=null&&il.matchIgnoreKey(item.getKey())){		
				if(!it.hasNext()){
					w.writeScopeChar('}');
					break;
				}
			
				continue ;
			}
			if(!isFirst){
				w.writeComma();
			
			}
			isFirst = false;
			if(il!=null){
				String policy = il.match(item.getKey());
				if(policy!=null){
					w.writeKey(item.getKey().toString());
					w.write(':');
					JsonTool.serializeJW(w,item.getValue(),policy);				
				
					if(!it.hasNext()){
						w.writeScopeChar(']');
						break;
					}
				}
				
			}
			//正常渲染
			if(item==null){
				w.writeValue("null");
			}else{				
				w.writeKey(item.getKey().toString());
				w.write(':');
				JsonTool.serializeJW(w,item.getValue(),node.getInHeritedPolicy());
			}
			
			if(!it.hasNext()){
				w.writeScopeChar('}');
				break;
			}
		
		
			
		}
	}
	
	public static void writeIterator(OutputNode node,Iterator it,JsonWriter w) throws IOException{
		
//		if(node.getInHeritedPolicy()!=null&&node.getInHeritedPolicy().length()!=0){
//			JsonTool.serializeJW(w,it,node.getInHeritedPolicy());
//			return ;
//		}
		
		IndexLocations il = node.getIndexLocation();
		int i = 0;
		if(!it.hasNext()){
			w.writeValue("[]");
			return ;
		}
		w.writeScopeChar('[');
		boolean isFirst = true;
		while(true){
			
			Object item = it.next();
			if(il!=null&&il.matchIgnoreKey(i)){		
				if(!it.hasNext()){
					w.writeScopeChar(']');
					break;
				}
				i++;
				continue ;
			}
			if(!isFirst){
				w.writeComma();
			
			}
			isFirst = false;
			if(il!=null){
				String policy = il.match(i);
				if(policy!=null){
//					System.out.println("serializeJW:"+"item="+item+"+++"+policy);
					if(node.getInHeritedPolicy()!=JsonTool.EMPTY_POLICY){
						JsonTool.serializeJW(w,item,policy+","+node.getInHeritedPolicy());	
					}else{
						JsonTool.serializeJW(w,item,policy);
					}
								
					i++;
					if(!it.hasNext()){
						w.writeScopeChar(']');
						break;
						
					}
					continue;
				}
				
			}
			//正常渲染
			if(item==null){
				w.writeValue("null");
			}else{				
				JsonTool.serializeJW(w,item,node.getInHeritedPolicy());
			}
			
			if(!it.hasNext()){
				w.writeScopeChar(']');
				break;
			}
			i++;
		
			
		}
		
	}
}
